﻿using Mapster;
using RuoVea.OmiApp.Template.Dto;
using RuoVea.OmiApp.Template.Language;
using RuoVea.ExDto;
using RuoVea.ExEnum;
using RuoVea.ExSugar;
using RuoVea.ExUtil;
using RuoVea.OmiApp.Template.Entitys;

namespace RuoVea.OmiApp.Template.Service;

/// <summary>
/// 字典值
/// </summary>
public class SysDictValueService : ISysDictValueService
{
    /// <summary>
    /// 
    /// </summary>
    public readonly SugarRepository<SysDictValue> _thisRepository;
    private readonly ICurrentUser _currentUser;
    /// <summary>
    /// 参数配置表
    /// </summary>
    /// <param name="thisRepository"></param>
    /// <param name="currentUser"></param>

    public SysDictValueService(SugarRepository<SysDictValue> thisRepository, ICurrentUser currentUser)
    {
        _thisRepository = thisRepository;
        _currentUser = currentUser;
    }

    /// <summary>
    /// 查询所有/分页
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult<PageResult<SysDictValueDto>>> GetPagesAsync(SysDictValueParam data)
    {
        var restful = new RestfulResult<PageResult<SysDictValueDto>>() { Code = CodeStatus.OK };
        bool supperAdmin = _currentUser.IsSuperAdmin;
        var code = !string.IsNullOrEmpty(data.Code?.Trim());
        var value = !string.IsNullOrEmpty(data.Value?.Trim());
        var typeId = data?.TypeId != null;
        var dictDatas = await _thisRepository.AsQueryable()
                              .Where(u => u.IsDelete == IsDelete.N && !supperAdmin || supperAdmin)
                              .WhereIF(typeId, u => u.TypeId == data!.TypeId)
                              .WhereIF(code, u => u.Code.Contains(data!.Code!))
                              .WhereIF(value, u => u.Value.Contains(data!.Value!))
                              .OrderBy(u => u.Sort)
                              .ToPageAsync<SysDictValue, SysDictValueDto>(data!.PageNo, data.PageSize);
        restful.Data = dictDatas;
        return restful;
    }

    /// <summary>
    /// 根据主键查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<RestfulResult<SysDictValueDto>> GetDataAsync(long id)
    {
        var restful = new RestfulResult<SysDictValueDto>() { Code = CodeStatus.OK };
        if (id == 0)
        {
            restful.Code = CodeStatus.BadRequest;
            restful.Message = i18n.getfail;
            return restful;
        }
        var model = await _thisRepository.AsQueryable().Where(x => x.IsDelete == IsDelete.N && x.Id == id).FirstAsync();
        restful.Data = model.Adapt<SysDictValueDto>();
        return restful;
    }



    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> AddDataAsync(SysDictValueDto data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };
        var isExist = await _thisRepository.IsAnyAsync(u => (u.Code == data.Code || u.Value == data.Value) && u.TypeId == data.TypeId);
        if (isExist)
        {
            restful.Message = ErrorEnum.D3003.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }
        var dictData = data.Adapt<SysDictValue>();
        bool result = await _thisRepository.InsertAsync(dictData);
        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.addsuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.addfail;
            return restful;
        }
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<RestfulResult> UpdateDataAsync(SysDictValueDto data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        var isExist = await _thisRepository.IsAnyAsync(u => u.Id == data.Id);
        if (!isExist)
        {
            restful.Message = ErrorEnum.D3004.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        // 排除自己并且判断与其他是否相同
        isExist = await _thisRepository.IsAnyAsync(u => (u.Value == data.Value || u.Code == data.Code) && u.TypeId == data.TypeId && u.Id != data.Id);
        if (isExist)
        {
            restful.Message = ErrorEnum.D3003.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        var dictData = data.Adapt<SysDictValue>();
        bool result = await _thisRepository.UpdateAsync(dictData, ignoreNullValues: true);
        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.modifysuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.modifyfail;
            return restful;
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public virtual async Task<RestfulResult> DeleteDataAsync(long id)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        if (id == 0)
        {
            restful.Message = i18n.deletefail;
            return restful;
        }
        var dictData = await _thisRepository.GetFirstAsync(u => u.Id == id);
        if (dictData == null)
        {
            restful.Message = ErrorEnum.D3004.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }
        bool isDelete = false;
        if (dictData!.IsDelete == IsDelete.Y)
        {
            isDelete = await _thisRepository.DeleteAsync(x => x.Id == id);
        }
        else
        {
            dictData.IsDelete = IsDelete.Y;
            isDelete = await _thisRepository.UpdateAsync(dictData);
        }

        if (isDelete)
        {
            restful.Message = i18n.deletesuccess;
            restful.Code = CodeStatus.OK; return restful;
        }
        else
        {
            restful.Message = i18n.deletefail;
            return restful;
        }
    }

    /// <summary>
    /// 获取某个字典类型下字典值列表
    /// </summary>
    /// <returns></returns>
    public async Task<RestfulResult<List<Dictionary<string, string>>>> GetDictDataListByCode(QueryDictValueListByCodeInput data)
    {
        RestfulResult<List<Dictionary<string, string>>> restful = new() { Code = CodeStatus.OK };

        restful.Data = await _thisRepository.Context.Queryable<SysDictType, SysDictValue>((a, b) => a.Id == b.TypeId).Where((a, b) => a.Code == data.Code && b.IsDelete == IsDelete.N)
            .OrderBy((a, b) => b.Sort)
            .Select((a, b) => new Dictionary<string, string> { { b.Value, b.Code } })
            .ToListAsync();
        return restful;
    }

    /// <summary>
    /// 修改字典值状态
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> ChangeDictDataStatus(ChageStateDictValueInput data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        var dictData = await _thisRepository.GetFirstAsync(u => u.Id == data.Id && u.IsDelete == IsDelete.N);
        if (dictData == null)
        {
            restful.Message = ErrorEnum.D3004.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        if (!data.Status.IsDefined<StatusEnum>())
        {
            restful.Message = ErrorEnum.D3005.GetDescription(ExDto.Language.i18n.ResourceManager);
            return restful;
        }

        dictData!.Status = data.Status;
        bool result = await _thisRepository.UpdateAsync(dictData);
        if (result)
        {
            restful.Code = CodeStatus.OK;
            restful.Message = i18n.modifysuccess;
            return restful;
        }
        else
        {
            restful.Message = i18n.modifyfail;
            return restful;
        }
    }

    #region NonAction
    /// <summary>
    /// 根据字典类型Id获取字典值集合
    /// </summary>
    /// <param name="dictTypeId"></param>
    /// <returns></returns>
    public async Task<List<SysDictValue>> GetDictValueListByDictTypeId(long dictTypeId)
    {
        return await _thisRepository.GetListAsync(u => u.TypeId == dictTypeId && u.Status == StatusEnum.ENABLE && u.IsDelete == IsDelete.N, u => u.Sort);
    }

    /// <summary>
    /// 删除字典下所有值
    /// </summary>
    /// <param name="dictTypeId"></param>
    public async Task DeleteByTypeId(long dictTypeId)
    {
        var dictDatas = await _thisRepository.GetListAsync(u => u.TypeId == dictTypeId && u.IsDelete == IsDelete.N);
        await _thisRepository.DeleteAsync(dictDatas);
    }

    /// <summary>
    /// 获取系统参数配置列表
    /// </summary>
    /// <returns></returns>
    public async Task<List<SysDictValue>> GetDataList()
    {
        return await _thisRepository.AsQueryable().Where(u => u.IsDelete == IsDelete.N).ToListAsync();
    }
    #endregion
}
